/**
* -----Tag folder-----
* http://code.google.com/p/tagfolder
* Licensed under LGPL
* chuanshenglu@gmail.com
* xrjieyee@gmail.com
*
*/

/**
*This is the server program of the TFDeamon;
*it runs at background, wait for incoming data;
*/

#if defined(__WINDOWS_PLATFORM__)
#   include <windows.h>
#   include <tchar.h>
#define WIN32_LEAN_AND_MEAN
#else // #if defined(__WINDOWS_PLATFORM__)
#   include <unistd.h>
#endif // #if defined(__WINDOWS_PLATFORM__)

#include <cstdlib>
#include <iostream>
#include "TFDeamon.h"
#include "TFNamedPipe.h"
#include "TFChannel.h"
#include "TFServerTask.h"
#include "TFServerBuffer.h"

int TF_ServerLoop(TFDuplexChannel&);
void OnExit();

#ifndef __CONSOLE_LOG__
#define __CONSOLE_LOG__
#endif

/**
*Entry of the whole deamon
*
*/
//int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hInstPrev,LPSTR,int nCmdShow)
#if defined( __WINDOWS_PLATFORM__)
int _tmain(int argc,TCHAR *argv[])
#elif defined(__GNU_PLATFORM__)
int main( int argc, char **argv)
#endif
{
	TFNamedPipe pipe;
	atexit(OnExit);

	//Link server end task handler;
	TFServerTaskDispatcher & dispatcher = *( TFServerTaskDispatcher::GetInstance ( ) );

	dispatcher.AddHandler ( TFMSG_ADDTAG , new TFSTaskOnAddTag ( ) ) ;
	dispatcher.AddHandler ( TFMSG_ADDFILE,	new TFSTaskOnAddFile( ) );
	dispatcher.AddHandler ( TFMSG_LINKTAGTOFILE, new TFSTaskOnLinkTagToFile() );
	dispatcher.AddHandler ( TFMSG_GETALLTAGS	, new TFSTaskOnGetAllTags( ) );
	dispatcher.AddHandler ( TFMSG_GETALLFILES	, new TFSTaskOnGetAllFiles ( ) );
	dispatcher.AddHandler ( TFMSG_GETTAGSOFFILE,	new TFSTaskOnGetTagsOfFile() );
	dispatcher.AddHandler ( TFMSG_GETFILESWITHTAG, new TFSTaskOnGetFilesWithTag( ) );
	dispatcher.AddHandler ( TFMSG_TERMINATESERVER, new TFSTaskOnTeminateServer( ) );
#ifdef __CONSOLE_LOG__
	std::cout<<"Add message handlers...\nStarting Deamon...\nDone!\nWaiting for client connections.\n"<<std::endl;
#endif
	//Enter main loop, infinite
	if(!pipe.CreatePipe()){ //Cann be block here
		return -1;
	}
	return TF_ServerLoop(pipe);
}

/**
*Long Loop to receive and dispatch client requests;
*The whole process can be block here;
*/
int TF_ServerLoop(TFDuplexChannel& channel)
{
	TFMessage msg;
	while(channel.Get(&msg,sizeof(msg))>0)
	{
		(TFServerTaskDispatcher::GetInstance())->Dispatch(msg,channel);
		if(msg.ID==TFMSG_TERMINATESERVER)
		{
			break;
		}

	}
	return 0;
}

//Clean up stuff;
void OnExit()
{
	delete TFServerTaskDispatcher::GetInstance();
	delete &(TFBufferManager::GetInstance());
}
